import com.troyworks.framework.logging.Logger;
import com.troyworks.framework.logging.ILogger;
import com.troyworks.framework.logging.LogLevel;
import com.troyworks.sos.SOS;
/**
 * A Class to log messages to the XMLSocket based SOSLogger from powerflasher
 * http://sos.powerflasher.de/english/english.html
 * 
 * this is based off the article 
 * http://blog.diefirma.de/2006-02-22/howto-fdt-mtasc-and-sos/
 * 
 * @author Troy Gardner
 */

class com.troyworks.framework.logging.SOSLogger extends Logger implements ILogger {
	public var owner : Object;
		public var sos : SOS;
	///////////////////////////////////
	public static var HIGHLIGHT:String = "HIGHLIGHT";
	public static var sock : XMLSocket;
	private static var instance : SOSLogger;
	public static var verbose : Boolean = false;
	public static var promptOnFatal:Boolean = false;
	public static var className : String = "com.troyworks.framework.logging.MTASC_TraceToSOS";

	public var initState:String = "-1";
	/*****************************************************
	 * Constructor
	 * not public in case a particular party wants a copy to customize the output to
	 * 
	 */
	public function SOSLogger(owner : Object) {
		super();
		initState = "0";
	 //WARNING NO TRACES BEFORE CREATION when using MTASC with -trace option to this class
	 //WARNING else Infinite loop trace("new SOSLogger");
		this.owner = owner;
		this.sos = new SOS();
		sos.showMessage("", "new SOSLogger");
		if(sos == null){
			var ss:SOS = new SOS();
			initState = "-2 "+ ss.getStatus();
		}else{
		initState = "1";
		setupStyles();
		sos.clearConsole();
		initState = "2";
		}
	}
	public static function getInstance(owner : String) : SOSLogger{
		if(SOSLogger.instance == null){
			SOSLogger.instance =  new SOSLogger(owner);
			SOSLogger.instance.info("SOSLoggerCreated by " + owner);
		   
		}
		return SOSLogger.instance;
	}
	public function setupStyles() : Void{
		var 	csock : XMLSocket = sos.getCommandSocket();
        for (var i : String in LogLevel) {
          var v:LogLevel = LogLevel(LogLevel[i]);
          if(v != null){
				csock.send("<setKey><name>"+v.name+"</name><color>"+v.value+"</color></setKey>\n");
        	}
        }
/*		csock.send("<setKey><name>SEVERE</name><color>"+0xee0000+"</color></setKey>\n");
		csock.send("<setKey><name>WARNING</name><color>"+0xFFcc00+"</color></setKey>\n");
		csock.send("<setKey><name>INFO</name><color>"+0xffcccc+"</color></setKey>\n");
		csock.send("<setKey><name>DEBUG</name><color>"+0xccffff+"</color></setKey>\n");

		csock.send("<setKey><name>START</name><color>"+0x63CF00+"</color></setKey>\n");
		csock.send("<setKey><name>END</name><color>"+0xCC6666+"</color></setKey>\n");

		csock.send("<setKey><name>HILIGHT_YELLOW</name><color>"+0xF7EB7B+"</color></setKey>\n");
		csock.send("<setKey><name>HILIGHT_ORANGE</name><color>"+0xFFD7A5+"</color></setKey>\n");
		csock.send("<setKey><name>HILIGHT_GRAPE</name><color>"+0xC671A5+"</color></setKey>\n");
		csock.send("<setKey><name>HILIGHT_SKYBLUE</name><color>"+0x9CD7F7+"</color></setKey>\n");
		csock.send("<setKey><name>HILIGHT_PURPLE</name><color>"+0xC6BAF7+"</color></setKey>\n");
		csock.send("<setKey><name>HILIGHT_LEMON</name><color>"+0xFFF3B5+"</color></setKey>\n");
		csock.send("<setKey><name>HILIGHT_LIME</name><color>"+0xCCFF99+"</color></setKey>\n");
		csock.send("<setKey><name>HILIGHT_TURQUOISE</name><color>"+0x73C3CE+"</color></setKey>\n");
		
		csock.send("<setKey><name>HILIGHT_GRAY1</name><color>"+0xF8F8F8+"</color></setKey>\n");
		csock.send("<setKey><name>HILIGHT_GRAY2</name><color>"+0xE1E1E1+"</color></setKey>\n");
	*/
	}

	////////////////////////////////////////////////////////////////////////////
	public function logBreak() : Void{
		SOSLogger.sock.send("-------------------------------------------------------------------");
	}
	public function clearLog() : Void{
		sos.clearConsole();
	}
	public function log( sMessage : String) : Void {

		SOSLogger.traceToSOS.apply(SOSLogger, arguments);
	}
	public function logLevel(nLevel : LogLevel, sMessage : String) : Void{
		//trace("<showMessage key='"+nLevel.name + "'>"+nLevel.name + " : "+sMessage+"</showMessage>\n");
		
		if(nLevel == LogLevel.FATAL){
			sos.showMessage(nLevel.name,sMessage);
			if(promptOnFatal){
				sos.createDialog(nLevel.name, sMessage);
			}
		}else{
			sos.showMessage(nLevel.name,sMessage);
		}
		//var 	csock : XMLSocket = sos.getCommandSocket();
		//csock.send("<showMessage key='"+nLevel.name + "'>"+nLevel.name + " : "+sMessage+"</showMessage>\n");
	}
	public static function MTASC_TraceToSOS(obj : Object, fullclass : String, file : String, line : Number) : Void{
		if(SOSLogger.getInstance().sos == null){
			var ss:SOS = new SOS();
			SOSLogger.getInstance().sos = ss;
			SOSLogger.getInstance().logLevel(LogLevel.WARNING, SOSLogger.getInstance().initState + " sos not inited!");
		}

		var msg : String = (verbose)?" nclass: " + fullclass + " nline: " + line + "" + " msg: " + obj:String(obj);

		if(typeof(obj) =="string"){
			var s : String = String(obj);
			var err : Boolean = s.indexOf("ERROR") >-1;
			var fI:Number = s.indexOf("FAILED");
			var failed:Boolean =  fI>-1 && (s.charAt(fI-1)!= "_" );
			var warn : Boolean = s.indexOf("WARNING") >-1;
			var info : Boolean = s.indexOf("INFO") >-1;
			var hiDX:Number = s.indexOf(HIGHLIGHT);
			var highlight : Boolean = hiDX >-1;
			var startO : Boolean = s.indexOf("\\\\\\\\\\\\\\\\") >-1;
			var endO : Boolean = s.indexOf("//////////////////") >-1;
			
			if(err){
				SOSLogger.getInstance().logLevel(LogLevel.SEVERE, msg);
				if(promptOnFatal){
					SOSLogger.getInstance().sos.createDialog("ERROR", msg);
				}
				return;
			}else if(failed){
				SOSLogger.getInstance().logLevel(LogLevel.FLASH_ERROR,msg);
				return;
								
			}else if(warn){
				SOSLogger.getInstance().logLevel(LogLevel.WARNING,msg);
				return;
			}else if(info){
				SOSLogger.getInstance().logLevel(LogLevel.INFO,msg);
				return;				
			}else if(highlight){
				//using the single letter/number after highlight
				// translate it into a suitable color
				var color:String = s.charAt((hiDX + HIGHLIGHT.length));
			//	trace("COLOR AT " + (hiDX + HIGHLIGHT.length + 1) + " is " + color);
				var ll:LogLevel = null;
				switch(color){
					case 'P':
						ll = LogLevel.HILIGHT_PURPLE;
						break;
					case 'B':
						ll = LogLevel.HILIGHT_TURQUOISE;
						break;
					case 'b':
						ll = LogLevel.HILIGHT_SKYBLUE;
						break;
					case 'G':
						ll = LogLevel.HILIGHT_LIME;
						break;
					case 'y':
						ll = LogLevel.HILIGHT_LEMON;
						break;

					case 'O':
						ll = LogLevel.HILIGHT_ORANGE;
						break;
					case 'V':
						ll = LogLevel.HILIGHT_GRAPE;
						break;		
					case '0':
						ll = LogLevel.HILIGHT_GRAY0;
						break;		
					case '1':
						ll = LogLevel.HILIGHT_GRAY1;
						break;		
					case '2':
						ll = LogLevel.HILIGHT_GRAY2;
						break;		
					case '3':
						ll = LogLevel.HILIGHT_GRAY3;
						break;		
					case '4':
						ll = LogLevel.HILIGHT_GRAY4;
						break;		
					case 'Y':
					default:
						ll = LogLevel.HILIGHT_YELLOW;
						break;
				}
				SOSLogger.getInstance().logLevel(ll,msg);
				return;				
			}else if(startO){
				SOSLogger.getInstance().logLevel(LogLevel.START,msg);
				return;				
			}else if(endO){
				SOSLogger.getInstance().logLevel(LogLevel.END,msg);
				return;				
				
			}
		}
		SOSLogger.getInstance().sos.showMessage(null,msg);
	}

	/**********************************************************
	 * The custom trace() function 
	 * 
	 * NOTE that it is static !
	 * so that when linked to in the -mtasc build options
	 * that it can be accessed  
	 * a MTASC build option should look something like
	 * 
	 * -swf build/default_mtasc.swf  -header 800:600:25 -version 8  -main  -trace "com.troyworks.framework.logging.SOSLogger.traceToSOS"
	 */
	public static function traceToSOS(obj : Object, fullclass : String, file : String, line : Number) : Void
	{
		SOSLogger.getInstance().sos.showMessage(null," nclass: " + fullclass + " nline: " + line + "" + "msg: " + obj );
	}
	public static function traceArray(obj : Object) : Void {
		for(var i:String in obj){
			traceToSOS("  " + i + " " + obj[i]);
		}
	}
	public function toString() : String{
		return SOSLogger.className;
		return null;
	}
}
